/** 
 * @description web本地数据库工具(indexedDB)
 * @author c-jw
 * @time 2020年3月31日 15:05:49
 */

export default function (dbname = 'mydb', version = 1) {
  let DB = {
    _db: null,
    dbname: 'mydb',
    version: 1,
    msg: "",
    init() {
      //创建应用仓库
      console.log('初始化对象仓库');
      let db = this._db;
      if (!db) {
        return console.error('[没有indexedDB数据库实例]')
      }
      //创建文档缓存仓库(当前编辑的文档)
      var Cache = db.createObjectStore('cache', {
        keyPath: 'id',
        unique: true //名称唯一
      });
      //创建文档仓库
      var Doc = db.createObjectStore('doc', {
        keyPath: 'id', //主键
        autoIncrement: true //自增
      });
      // 文档索引 (名称索引)
      Doc.createIndex('name', 'name', {
        unique: true, //名称唯一
      });
    },

    dbOpen() {
      if (!window.indexedDB) {
        return window.alert("当前浏览器不支持IndexedDB数据库");
      }
      var dbname = this.dbname;
      var version = this.version;
      var IDB = indexedDB.open(dbname, version);
      IDB.addEventListener('upgradeneeded', e => {
        // 要创建一个对象仓库必须在upgradeneeded事件中，而upgradeneeded事件只会在版本号更新的时候触发，
        // 这是因为IndexedDB API中不允许数据库中的数据仓库在同一版本中发送变化
        this._db = e.target.result;
        this.init(); //初始化对象仓库(当前编辑的文档)
      })
      return IDB;
    },
    store: function (storeName, callback, mode) {
      let dbCon = this.dbOpen();
      if (dbCon) {
        dbCon.addEventListener('success', e => {
          // console.log("%c %s %O", "color:green", "[数据库连接成功]", e.target.result);
          let db = e.target.result;
          let store = db.transaction(storeName, mode || 'readwrite').objectStore(storeName);
          callback && callback(store);
        });
        dbCon.addEventListener('error', e => {
          console.log("%c %s %O", "color:red", "[连接数据库失败]", e);
        });
      }
      return dbCon;
    },
    put: function (storeName, data, callback) {
      return this.store(storeName, (store) => {
        let res = store.put(data);
        res.addEventListener('success', callback);
        res.addEventListener('error', callback);
      });
    },
    get: function (storeName, primaryKey, callback) {
      return this.store(storeName, (store) => {
        let res = store.get(primaryKey);
        res.addEventListener('success', callback);
        res.addEventListener('error', callback);
      });
    },
    find: function (storeName, callback) {
      return this.store(storeName, (store) => {
        let res = store.openCursor(null, 'prev');
        res.addEventListener('success', callback);
        res.addEventListener('error', callback);
      });
    },
    del: function (storeName, id, callback) {
      return this.store(storeName, (store) => {
        let res = store.delete(id);
        res.addEventListener('success', callback);
        res.addEventListener('error', callback);
      });
    }
  };
  DB.dbname = dbname;
  DB.version = version;
  return DB;
}